package org.frog.sgs.io;

import java.util.ArrayList;
import java.util.List;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.frog.sgs.consts.Constants;
import org.frog.sgs.util.SgsUtils;

/**
 * @author duanxiangqi
 * @date 2012-10-22
 */
public class SgsProtocolDecoder extends ProtocolDecoderAdapter {

	@SuppressWarnings("unchecked")
	public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
		while (in.hasRemaining()) {
			SgsMsg msg = (SgsMsg) session.getAttribute(Constants.SESSION_KEY_TEMP_MSG);
			if (msg == null) {
				msg = new SgsMsg();
				session.setAttribute(Constants.SESSION_KEY_TEMP_MSG, msg);
			}
			// System.out.println(msg.getCode() + "," + msg.getLength() + "," +
			// msg.getPosition() + ":" + in);
			if (msg.getCode() < 0) {
				List<Byte> bytes = (List<Byte>) session.getAttribute(Constants.SESSION_KEY_TEMP_BYTES);
				if (bytes == null) {
					bytes = new ArrayList<Byte>();
					session.setAttribute(Constants.SESSION_KEY_TEMP_BYTES, bytes);
				}
				if (bytes.size() == 4) {
					byte[] temp = new byte[4];
					for (int i = 0; i < temp.length; i++) {
						temp[i] = bytes.get(i);
					}
					msg.setCode(SgsUtils.instance.byte2int(temp));
					session.removeAttribute(Constants.SESSION_KEY_TEMP_BYTES);
				} else {
					bytes.add(in.get());
				}
			} else if (msg.getLength() < 0) {
				List<Byte> bytes = (List<Byte>) session.getAttribute(Constants.SESSION_KEY_TEMP_BYTES);
				if (bytes == null) {
					bytes = new ArrayList<Byte>();
					session.setAttribute(Constants.SESSION_KEY_TEMP_BYTES, bytes);
				}
				if (bytes.size() == 4) {
					byte[] temp = new byte[4];
					for (int i = 0; i < temp.length; i++) {
						temp[i] = bytes.get(i);
					}
					msg.setLength(SgsUtils.instance.byte2int(temp));
					session.removeAttribute(Constants.SESSION_KEY_TEMP_BYTES);
				} else {
					bytes.add(in.get());
				}
			} else if (msg.getLength() == 0) {
				msg.readToBuffer();
				out.write(msg);
				session.removeAttribute(Constants.SESSION_KEY_TEMP_MSG);
			} else if (msg.getPosition() < msg.getLength()) {
				msg.writeByte(in.get());
				msg.setPosition(msg.getPosition() + 1);
				if (msg.getPosition() == msg.getLength()) {
					out.write(msg);
					session.removeAttribute(Constants.SESSION_KEY_TEMP_MSG);
				}
			} else {
				System.err.println("消息处理出错!" + in);
				System.exit(0);
			}
		}
	}
}
